package com.linkallcloud.core.www.utils;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class OkHttpUtils {
    public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
    private static OkHttpUtils okHttpUtils;
    private static OkHttpClient okHttpClient;

    /**
     * 构造初始化
     */
    private OkHttpUtils() {
        /**
         * 构建OkHttpClient
         */
        okHttpClient = new OkHttpClient.Builder()
                /**
                 * 请求的超时时间
                 */
                .readTimeout(5000, TimeUnit.MILLISECONDS)
                /**
                 * 设置响应的超时时间
                 */
                .writeTimeout(5000, TimeUnit.MILLISECONDS)
                /**
                 * 设置连接的超时时间
                 */
                .connectTimeout(5000, TimeUnit.MILLISECONDS)
                /**
                 * 配置SSL信任
                 */
                .hostnameVerifier(OkSSLSocketClient.getHostnameVerifier())
                .sslSocketFactory(OkSSLSocketClient.getSSLSocketFactory(), OkSSLSocketClient.getX509TrustManager())
                /**
                 * 构建
                 */
                .build();
    }

    /**
     * 通过单例模式构造对象
     * 
     * @return
     */
    public static OkHttpUtils me() {
        if (okHttpUtils == null) {
            synchronized (OkHttpUtils.class) {
                if (okHttpUtils == null) {
                    okHttpUtils = new OkHttpUtils();
                }
            }
        }
        return okHttpUtils;
    }

    /**
     * 
     * @param url
     * @return
     */
    public CompletableFuture<String> get(String url) {
        Request request = new Request.Builder().url(url).get().build();
        return deliveryResult(okHttpClient.newCall(request));
    }

    /**
     * 
     * @param url
     * @param requestBody
     * @return
     */
    public CompletableFuture<String> post(String url, RequestBody requestBody) {
        Request request = new Request.Builder().url(url).post(requestBody).build();
        return deliveryResult(okHttpClient.newCall(request));
    }

    /**
     * 
     * @param url
     * @param jsonStr
     * @return
     */
    public CompletableFuture<String> postJson(String url, String jsonStr) {
        RequestBody body = RequestBody.create(jsonStr, JSON);
        Request request = new Request.Builder().url(url).post(body).build();
        return deliveryResult(okHttpClient.newCall(request));
    }

    /**
     * 处理请求结果的回调
     * 
     * @param call
     * @return
     */
    private CompletableFuture<String> deliveryResult(Call call) {
        CompletableFuture<String> completableFuture = new CompletableFuture<>();
        call.enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                completableFuture.completeExceptionally(e);
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                try (ResponseBody responseBody = response.body()) {
                    if (!response.isSuccessful()) {// 响应状态码异常
                        completableFuture.completeExceptionally(new IOException("Unexpected code " + response.code()));
                    } else { // 成功
                        completableFuture.complete(responseBody.string());
                    }
                }
            }
        });
        return completableFuture;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 1.阻塞等待返回
        CompletableFuture<String> f = OkHttpUtils.me().get("https://www.baidu.com");
        String response = f.get();
        System.out.println(response);

        // 2.非阻塞
        OkHttpUtils.me().get("https://www.baidu.com").thenAccept(responseText -> {
            System.out.println(responseText);
        }).exceptionally(e -> {
            System.out.println(e.getMessage());
            return null;
        });
    }

}
